<template>
    <div>
        <!-- 表头分页查询条件， shadow="never" 指定 card 卡片组件没有阴影 -->
        <el-card shadow="never" class="mb-5">
            <!-- flex 布局，内容垂直居中 -->
            <div class="flex items-center">
                <el-text>文章标题</el-text>
                <div class="ml-3 w-52 mr-5"><el-input v-model="searchArticleTitle" placeholder="请输入（模糊查询）" /></div>

                <el-text>创建日期</el-text>
                <div class="ml-3 w-30 mr-5">
                    <!-- 日期选择组件（区间选择） -->
                    <el-date-picker v-model="pickDate" type="daterange" range-separator="至" start-placeholder="开始时间"
                        end-placeholder="结束时间" size="default" :shortcuts="shortcuts" @change="datepickerChange" />
                </div>

                <el-button type="primary" class="ml-3" :icon="Search" @click="getTableData">查询</el-button>
                <el-button class="ml-3" :icon="RefreshRight" @click="reset">重置</el-button>
            </div>
        </el-card>

        <el-card shadow="never">
            <!-- 写文章按钮 -->
            <div class="mb-5">
                <el-button @click="isEditArticleDialogVisible = true" type="primary">
                    <el-icon class="mr-1">
                        <EditPen />
                    </el-icon>
                    写文章</el-button>
            </div>

            <!-- 分页列表 -->
            <el-table :data="tableData" border stripe style="width: 100%" v-loading="tableLoading">
                <el-table-column prop="title" label="标题" width="240" />
                <el-table-column prop="cover" label="封面" width="120">
                    <!-- 展示图片 -->
                    <template #default="scope">
                        <el-image style="width: 50px;" :src="scope.row.cover" />
                    </template>
                </el-table-column>
                <el-table-column prop="createTime" label="发布时间" width="180" />
                <el-table-column prop="isTop" label="置顶" width="80">
                    <template #default="scope">
                        <!-- switch -->
                         <el-switch v-model="scope.row.isTop" :active-value="true" :inactive-value="false"
                            @change="handleSwitchChange(scope.row.id, scope.row.isTop)" />
                    </template>
                </el-table-column>
                <el-table-column label="操作">
                    <template #default="scope">
                        <el-button @click="showArticleUpdateEditor(scope.row)" size="small">
                            <el-icon class="mr-1">
                                <Edit />
                            </el-icon>
                            编辑</el-button>
                        <el-button @click="handleDelete(scope.row.id)" type="danger" size="small">
                            <el-icon class="mr-1">
                                <Delete />
                            </el-icon>
                            删除
                        </el-button>
                    </template>
                </el-table-column>
            </el-table>

            <!-- 分页 -->
            <div class="mt-10 flex justify-center">
                <el-pagination v-model:current-page="current" v-model:page-size="size" :page-sizes="[5, 10, 20]"
                    :small="false" :background="true" layout="total, sizes, prev, pager, next, jumper" :total="total"
                    @size-change="handleSizeChange" @current-change="getTableData" />
            </div>

        </el-card>

        <!-- 写博客 -->
        <el-dialog v-model="isEditArticleDialogVisible" :fullscreen="true" :show-close="false">
            <template #header="{ close, titleId, titleClass }">
                <!-- 指定 flex 布局， 高度为 10， 背景色为白色 -->
                <div class="flex h-10 bg-white">
                    <!-- 字体加粗 -->
                    <h4 class="font-bold">写文章</h4>
                    <!-- 靠右对齐 -->
                    <div class="ml-auto flex">
                        <el-button @click="isEditArticleDialogVisible = false">取消</el-button>
                        <el-button @click="addArticle" type="primary">
                            <el-icon class="mr-1">
                                <Promotion />
                            </el-icon>
                            发布
                        </el-button>
                    </div>
                </div>

            </template>
            <!-- CONTENT -->
            <!-- label-position="top" 用于指定 label 元素在上面 -->
            <el-form :model="formValue" ref="publishArticleFormRef" label-position="top" size="large" :rules="rules">
                <el-form-item class="w-[260px]" label="标题" prop="title">
                    <el-input v-model="formValue.title" autocomplete="off" size="large" maxlength="20" show-word-limit
                        clearable />
                </el-form-item>
                <el-form-item label="内容" prop="content">
                    <!-- Markdown 编辑器 -->
                    <MdEditor v-model="formValue.content" @on-upload-img="onUploadImg" editor-id="publishArticleEditor"
                        class="editor"></MdEditor>
                </el-form-item>
                <el-form-item label="封面" prop="cover">
                    <el-upload class="avatar-uploader" :on-change="handleCoverChange" action="#" :auto-upload="false"
                        :show-file-list="false">
                        <img v-if="formValue.cover" :src="formValue.cover" class="avatar" />
                        <el-icon v-else class="avatar-uploader-icon">
                            <Plus />
                        </el-icon>
                    </el-upload>
                </el-form-item>
                <el-form-item label="摘要" prop="summary">
                    <!-- :rows="3" 指定 textarea 默认显示 3 行 -->
                    <el-input v-model="formValue.summary" :rows="3" type="textarea" placeholder="请输入文章摘要" />
                </el-form-item>
                <el-form-item label="分类" prop="categoryId" style="width: 220px;">
                    <el-select v-model="formValue.categoryId" clearable placeholder="---请选择---" size="default">
                        <el-option v-for="item in categoryList" :key="item.value" :label="item.label"
                            :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item label="标签" prop="tags" style="width: 220px;">
                    <!-- 标签选择 -->
                    <el-select v-model="formValue.tags" :remote-method="handleTagSearch" multiple filterable remote
                        reserve-keyword placeholder="---请输入---" remote-show-suffix allow-create default-first-option
                        size="default">
                        <el-option v-for="item in tags" :key="item.value" :label="item.label" :value="item.value" />
                    </el-select>
                </el-form-item>
            </el-form>
        </el-dialog>



        <!-- 编辑文章 -->
        <el-dialog v-model="isArticleUpdateEditorShow" :fullscreen="true" :show-close="false"
            :close-on-press-escape="false">
            <template #header="{ close, titleId, titleClass }">
                <!-- 指定 flex 布局， 高度为 10， 背景色为白色 -->
                <div class="flex h-10 bg-white">
                    <!-- 字体加粗 -->
                    <h4 class="font-bold">编辑文章</h4>
                    <!-- 靠右对齐 -->
                    <div class="ml-auto flex">
                        <el-button @click="isArticleUpdateEditorShow = false">取消</el-button>
                        <el-button type="primary" @click="updateSubmit">
                            <el-icon class="mr-1">
                                <Promotion />
                            </el-icon>
                            保存
                        </el-button>
                    </div>
                </div>
            </template>
            <!-- label-position="top" 用于指定 label 元素在上面 -->
            <el-form :model="updateArticleForm" ref="updateArticleFormRef" label-position="top" size="large"
                :rules="rules">
                <el-form-item label="标题" prop="title">
                    <el-input v-model="updateArticleForm.title" autocomplete="off" size="large" maxlength="40"
                        show-word-limit clearable />
                </el-form-item>
                <el-form-item label="内容" prop="content">
                    <!-- Markdown 编辑器 -->
                    <MdEditor v-model="updateArticleForm.content" @onUploadImg="onUploadImg"
                        editorId="updateArticleEditor" />
                </el-form-item>
                <el-form-item label="封面" prop="cover">
                    <el-upload class="avatar-uploader" action="#" :on-change="handleUpdateCoverChange"
                        :auto-upload="false" :show-file-list="false">
                        <img v-if="updateArticleForm.cover" :src="updateArticleForm.cover" class="avatar" />
                        <el-icon v-else class="avatar-uploader-icon">
                            <Plus />
                        </el-icon>
                    </el-upload>
                </el-form-item>
                <el-form-item label="摘要" prop="summary">
                    <!-- :rows="3" 指定 textarea 默认显示 3 行 -->
                    <el-input v-model="updateArticleForm.summary" :rows="3" type="textarea" placeholder="请输入文章摘要" />
                </el-form-item>
                <el-form-item label="分类" prop="categoryId" class="w-[220px]">
                    <el-select v-model="updateArticleForm.categoryId" clearable placeholder="---请选择---" size="default">
                        <el-option v-for="item in categoryList" :key="item.value" :label="item.label"
                            :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item label="标签" prop="tags" class="w-[220px]">
                    <span class="w-60">
                        <!-- 标签选择 -->
                        <el-select v-model="updateArticleForm.tags" multiple filterable remote reserve-keyword
                            placeholder="请输入文章标签" remote-show-suffix allow-create default-first-option
                            :remote-method="handleTagSearch" :loading="searchTagLoading" size="default">
                            <el-option v-for="item in tags" :key="item.value" :label="item.label" :value="item.value" />
                        </el-select>
                    </span>
                </el-form-item>
            </el-form>
        </el-dialog>
    </div>
</template>

<script setup>
import { ref, reactive, onBeforeMount, watch } from 'vue'
import { Search, RefreshRight, FullScreen } from '@element-plus/icons-vue'
import moment from 'moment'
import { getTagList } from '@/api/admin/tag'
import { deleteArticle, getArticleDetail, getArticlePageList, getCategorySelectList, getTagSelectList, publishArticle, updateArticle, updateArticleIsTop } from '@/api/admin/article'
import { showConfirm, showMessage } from '@/composables/utils';
import { MdEditor } from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';
import { uploadFile } from '@/api/admin/file';
import { useRoute } from 'vue-router'

//==============================分页(表格)数据==========================
// 模糊搜索的文章标题
const searchArticleTitle = ref('')
// 表格加载 Loading
const tableLoading = ref(false)
// 表格数据
const tableData = ref([])
// 当前页码，给了一个默认值 1
const current = ref(1)
// 总数据量，给了个默认值 0
const total = ref(0)
// 每页显示的数据量，给了个默认值 10
const size = ref(10)
// 获取分页数据
const getTableData = () => {
    //根据查询条件查询 table
    tableLoading.value = true   //开启 loading
    getArticlePageList({
        title: searchArticleTitle.value,
        startDate: startDate.value,
        endDate: endDate.value,
    }).then(res => {
        if (res.success) {
            tableData.value = res.data
            total.value = res.total
            // size.value = res.size
            current.value = res.current
        }
    }).finally(() => {
        tableLoading.value = false
    })
}
// 获取下拉分类列表
const categoryList = ref([])
const getCategory = () => {
    getCategorySelectList().then(res => {
        if (!res.success) {
            showMessage(res.message, 'error')
            return
        }
        categoryList.value = res.data
    })
}
onBeforeMount(() => {
    getTableData()
    getCategory()
})


//===========================写文章========================
const isEditArticleDialogVisible = ref(false)
const publishArticleFormRef = ref(null)
const formValue = reactive({
    title: '',
    cover: '',
    content: '',
    summary: '',
    tags: [],
    categoryId: ''
})
const rules = reactive({
    title: [
        { required: true, message: '请输入文章标题', trigger: 'blur' },
        { min: 1, max: 40, message: '文章标题要求大于1个字符，小于40个字符', trigger: 'blur' },
    ],
    content: [{ required: true }],
    categoryId: [{ required: true, message: '请选择文章分类', trigger: 'blur' }],
    tags: [{ required: true, message: '请选择文章标签', trigger: 'blur' }],
})
// 封面上传
const handleCoverChange = (file) => {
    let formData = new FormData()
    formData.append('file', file.raw)
    uploadFile(formData).then((res) => {
        if (!res.success) {
            showMessage(res.message, 'error')
            return
        }
        formValue.cover = res.data.url
        showMessage('上传成功!', 'success')
    })
}
// 文章图片上传
const onUploadImg = async (files, callback) => {
    const res = await Promise.all(
        files.map(file => {
            return new Promise((resolve, reject) => {
                console.log('---> 编辑器开始上传文件')
                let formData = new FormData()
                formData.append('file', file)
                uploadFile(formData).then(res => {
                    callback([res.data.url])    //调用callback,回显上传图片
                })
            })
        })
    )
}
// 模糊标签查询
const tags = ref([])
const searchTagLoading = ref(false)
const handleTagSearch = (key) => {
    if (key) {
        searchTagLoading.value = true
        getTagSelectList(key).then(res => {
            if (!res.success) {
                showMessage(res.message, 'error')
                return
            }
            tags.value = res.data
        }).finally(() => {
            searchTagLoading.value = false
        })
    }
}
// 文章发布
const addArticle = () => {
    publishArticleFormRef.value.validate((valid) => {
        if (!valid) {
            return false
        }
        publishArticle(formValue).then(res => {
            if (!res.success) {
                showMessage(res.message, 'error')
                return
            }
            showMessage('发布成功', 'success')
            isEditArticleDialogVisible.value = false
            formValue.title = ''
            formValue.cover = ''
            formValue.content = ''
            formValue.summary = ''
            formValue.categoryId = ''
            formValue.tags = []
            getTableData()
        })
    })
}

//===========================编辑文章==========================
const isArticleUpdateEditorShow = ref(false)
const updateArticleFormRef = ref(null)
const updateArticleForm = reactive({
    title: '',
    cover: '',
    content: '',
    summary: '',
    categoryId: '',
    tags: [],
})

const handleUpdateCoverChange = (file) => {
    let formData = new FormData()
    formData.append('file', file.raw)
    uploadFile(formData).then((res) => {
        if (!res.success) {
            showMessage(res.message, 'error')
            return
        }
        updateArticleForm.cover = res.data.url
        showMessage('上传成功!', 'success')
    })
}
// 根据编辑按钮的 row显示编辑文章的Dialog
const showArticleUpdateEditor = (row) => {
    isArticleUpdateEditorShow.value = true
    getArticleDetail(row.id).then(res => {
        if (res.success) {
            updateArticleForm.id = res.data.id
            updateArticleForm.title = res.data.title
            updateArticleForm.cover = res.data.cover
            updateArticleForm.content = res.data.content
            updateArticleForm.summary = res.data.summary
            updateArticleForm.categoryId = res.data.categoryId
            updateArticleForm.tags = res.data.tagIds
        }
    })
}
getTagList().then(res => {
    if (!res.success) {
        showMessage(res.message, 'error')
        return
    }
    tags.value = res.data
})
const updateSubmit = () => {
    // 表单校验
    updateArticleFormRef.value.validate((valid) => {
        if (!valid) {
            showMessage('表单校验失败', 'error')
            return false
        }
        updateArticle(updateArticleForm).then(res => {  //发送更新文章请求
            if (!res.success) {
                showMessage(res.message, 'error')
                return false
            }
            showMessage('更新文章成功', 'success')
            isArticleUpdateEditorShow.value = false
            getTableData()
        })
    })
}
//监听路由变化
const route = useRoute()
watch(() => route.path, (n, o) => {
    isArticleUpdateEditorShow.value = false
    isEditArticleDialogVisible.value = false
})



// 删除文章
const handleDelete = (id) => {
    showConfirm("确定删除这篇文章吗?").then(() => {
        deleteArticle(id).then(res => {
            if (res.success == false) {
                let message = res.message
                showMessage(message, 'error')
                return
            }
            showMessage("删除成功")
            getTableData()
        }).catch(() => {
            console.log("delete canceled")
        })
    }).catch(() => {
        showMessage("delete canceled", 'info')
    })
}

// 每页展示数量变更事件
const handleSizeChange = (chooseSize) => {
    console.log('选择的页码' + chooseSize)
    size.value = chooseSize
    getTableData()
}

// 文章是否置顶
const handleSwitchChange = (id, isTop) => {
    console.log('文章id：' + id + ', 是否置顶：' + isTop)
    updateArticleIsTop({
        id: id,
        isTop: isTop
    }).then(res => {
        if( res.success){
            tableLoading.value = true
            getTableData()
            showMessage('操作成功', 'success')
        }else{
            showMessage(res.message, 'error')
        }
    }).finally(() => {
        tableLoading.value = false
    })
}


// 重置
const reset = () => {
    pickDate.value = ''
    startDate.value = null
    endDate.value = null
    searchArticleTitle.value = ''
}


//==============================日期==========================
const pickDate = ref('')
// 查询条件：开始结束时间
const startDate = reactive({})
const endDate = reactive({})

// 监听日期组件改变事件，并将开始结束时间设置到变量中
const datepickerChange = (e) => {
    startDate.value = moment(e[0]).format('YYYY-MM-DD')
    endDate.value = moment(e[1]).format('YYYY-MM-DD')

    console.log('开始时间：' + startDate.value + ', 结束时间：' + endDate.value)
}

const shortcuts = [
    {
        text: '最近一周',
        value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
            return [start, end]
        },
    },
    {
        text: '最近一个月',
        value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
            return [start, end]
        },
    },
    {
        text: '最近三个月',
        value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
            return [start, end]
        },
    },
]

</script>

<style>
/* 解决 textarea :focus 状态下，边框消失的问题 */
.el-textarea__inner:focus {
    outline: 0 !important;
    box-shadow: 0 0 0 1px var(--el-input-focus-border-color) inset !important;
}

.md-editor-footer {
    height: 36px;
}

.avatar-uploader .el-upload {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
    border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 100px;
    height: 100px;
    text-align: center;
}
</style>
<style scoped>
/* 封面图片样式 */
.avatar-uploader .avatar {
    width: 200px;
    height: 100px;
    display: block;
}

.el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 200px;
    height: 100px;
    text-align: center;
}
</style>